package com.ady.util;

import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <b>description</b>：id生成器 <br>
 * <b>time</b>：2017-7-31下午3:00:38 <br>
 * <b>author</b>： ready likun_557@163.com
 */
public class IDUtil {

    private static Logger logger = Logger.getLogger(IDUtil.class);
    /**
     * 分片生成id
     */
    /**
     * 分片数量
     */
    private static int shardSize = 10;
    /**
     * 每个分片中生成的id的数量
     */
    private static int initSize = 1000;
    private static List<ArrayBlockingQueue<String>> shardList = new ArrayList<>();

    static {
        for (int i = 0; i < shardSize; i++) {
            final ArrayBlockingQueue<String> idBuffer = new ArrayBlockingQueue<String>(
                    initSize);
            shardList.add(idBuffer);
            Thread thread = new Thread() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            idBuffer.put(generateId());
                        } catch (Exception e) {
                            logger.error(e.getMessage(), e);
                        }
                    }
                }
            };
            thread.setDaemon(true);
            thread.start();
        }
    }

    /**
     * 生成id
     *
     * @return
     */
    private static String generateId() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 获取id
     *
     * @return
     * @throws InterruptedException
     */
    public static String getId() {
        try {
            int shareIndex = Long.valueOf(System.currentTimeMillis() % shardSize).intValue();
            return shardList.get(shareIndex).take();
        } catch (Exception e) {
            return generateId();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(2000);
        for (int i = 0; i < 5; i++) {
            test1();
        }
    }

    static void test1() {
        final List<Long> stList = Collections
                .synchronizedList(new ArrayList<Long>());
        long startTime = System.currentTimeMillis();
        int size = 10;
        final CountDownLatch latch = new CountDownLatch(size);
        ExecutorService executorService = Executors
                .newScheduledThreadPool(size);
        for (int i = 0; i < size; i++) {
            executorService.execute(new Runnable() {
                public void run() {
                    try {
                        int j = 0;
                        while (true) {
                            long st = System.currentTimeMillis();
                            IDUtil.getId();
                            stList.add(System.currentTimeMillis() - st);
                            if (++j == 100) {
                                break;
                            }
                        }
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    } finally {
                        latch.countDown();
                    }
                }
            });
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
        }
        executorService.shutdown();
        System.out
                .println("耗时(ms):" + (System.currentTimeMillis() - startTime));
        System.out.println(stList.size());
        System.out.println(Collections.max(stList));
    }
}
